Linguaggio C

 

per collaborazioni, commenti, critiche, e altro contattateci alla e-mail: clubinfo@libero.it risponderemo al più presto!

Panoramica del linguaggio

di Luca Sabatucci

Lezione 2

Pagina principale | Lezione precedente | Lezione successiva


Struttura generale di un programma C

In questa prima lezione daremo uno sguardo veloce su alcune delle funzionalità del linguaggio, senza entrare in dettaglio, lasciando alle prossime puntate il compito di approfondire.

Questa lezione è dedicata a tutti coloro che non conoscono il linguaggio C (gruppi I e II). Si tenga conto che non è necessario comprendere ogni parola di questa lezione per continuare il corso. Molte cose sono soltanto accennate e verranno riprese in seguito con maggior dettaglio.
Adesso iniziamo...

Un programma in C è formato da alcune entità ben definite che sono:

Le direttive di precompilazione sono una parte di codice che ha come scopo di comunicare qualcosa al compilatore, come ed esempio che il sorgente deve essere linkato ad dei file specificati, oppure serve a definire delle macro.
La definizione di legami globali è un modo sintetico (e lo ammetto un po criptico) per dire che vengono definite delle variabili globali e delle funzioni globali.
La funzione main rappresenta il punto di inizio del programma.

Vediamo un breve esempio di listato per il calcolo della circonferenza:


#include <stdio.h>

const pigreco=3.14;

int main() {
	double raggio;

	printf("Introdurre il raggio della circonferenza: ");
	scanf("%d",&raggio);

	printf("Circonferenza: %d",2*pigreco*raggio);

	return 0;
}

In questo piccolo listato sono racchiusi tutti gli elementi di sopra. Analizziamo uno per uno:

#include <stdio.h>

Tutte le direttive di precompilazione iniziano con il carattere # (cancelletto). La direttiva include seguita da un nome di file tra le parentesi triangolari indica che tale file deve essere incluso nella costruzione del file oggetto. In questo caso si sta includendo il file stdio.h che sta per Standard Input Output Library. Si tratta di una libreria che appartiene allo standard ANSI fornita con tutti i compilatori C (in qualunque ambiente e sistema operativo).
Questa libreria (come si intuisce dal nome) fornisce gli strumenti per effettuare operazioni di input e output da e verso le periferiche di sistema. Nel listato abbiamo effettuato questa inclusione perché più sotto usiamo due funzioni di tale libreria: printf e scanf.

const pigreco=3.14;

Questa è una dichiarazione di costante che ha visibilità globale. Ovvero in qualunque parte del programma si può accedere al valore della costante pi greco. E' la posizione in cui si effettua la dichiarazione a definirne la visibilità (che da adesso chiameremo scopo). Una variabile, una costante o una funzione definite all'esterno di una qualunque funzione hanno scopo globale. Se la variabile, o la costante vengono dichiarate dentro una funzione si dice che hanno scopo locale. Questo concetto è molto importante per cui vedremo di chiarirlo in seguito.


int main() {
	double raggio;

	printf("Introdurre il raggio della circonferenza: ");
	scanf("%d",&raggio);

	printf("Risultato: %d",2*pigreco*raggio);

	return 0;
}

In questa sezione vediamo tre concetti. La definizione di una funzione, la definizione di una variabile locale e l'uso di una funzione.
La forma per definire una funzione in C, è:


[tipo restituito] [nome della funzione] "(" [lista (eventualmente vuota) degli argomenti] ")" "{"
	[sequenza istruzioni]
"}"

Non ci soffermeremo più di così per il momento sulla forma di una funzione, ma diciamo solo che la main è a tutti gli effetti una funzione. Tutto ciò che sta dentro le due parentesi graffe { ... } è la sequenza di istruzioni che ci permette di calcolare la circonferenza
Nella sezione:


	double raggio;

si dichiara una variabile di nome raggio e di tipo numero reale a doppia precisione. Tale variabile, a differenza della costante dichiarata fuori dalla main è di tipo locale. Ciò significa che esiste soltanto dentro la funzione. Se venisse usata al di fuori di essa il compilatore genererebbe un errore.
Adesso iniziano le istruzioni che fanno effettivamente quello che ci si aspetti:


	printf("Introdurre il raggio della circonferenza: ");
	scanf("%d",&raggio);

	printf("Risultato: %d",2*pigreco*raggio);

Abbiamo già detto che printf e scanf sono delle funzioni che appartengono alla libreria stdio.h. Si tratta di due funzioni estremamente utili.
La printf permette di scrivere qual cosa sullo standard output, che generalmente è il monitor, mentre la scanf chiede all'utente di introdurre qualcosa dallo standard input, generalmente la tastiera.
L'uso di una funzione è estremamente semplice, come si può vedere; è sufficiente conoscere quale è la lista dei parametri che è necessario fornire in ingresso.
Il significato delle istruzioni è (in breve) questo: si stampa su schermo un prompt con la richiesta di inserire dei dati, quindi si aspetta che l'utente inserisca un numero e si stampa il risultato.
L'ultima istruzione:


	return 0;

indica alla funzione di uscire e restituire un valore che in questo caso è zero. Uscire dalla main significa terminare il programma. Il valore restituito può servire per indicare al sistema operativo qualcosa, ad esempio se il programma è terminato correttamente o è accaduto qualche errore.

Strutturare un programma

L'uso delle funzioni permette al programmatore di astrarre alcuni concetti per poter lavorare più velocemente. Nell'esempio di sopra, non ci siamo preoccupati di sapere come fanno le funzioni printf e scanf a interagire con il monitor e con la tastiera.
Questo è uno dei concetti più importanti della programmazione moderna. In questo caso le due funzioni rappresentano i mattoncini che abbiamo usato per costruire un programma che effettivamente fa qualche cosa di più "ad alto livello".
Se avessimo deciso di costruire direttamente noi le funzioni che interagiscono con le periferiche, avremmo ottenuto un codice sicuramente più lungo, più complesso e con qualche errore...

Oltre alle funzioni di sistema, il programmatore può contribuire con le proprie funzioni. Facciamo un esempio direttamente derivato dal precedente.


#include<stdio.h>

const pigreco=3.14;

double calcola_circonferenza(double raggio);

int main() {
	double raggio;

	printf("Introdurre il raggio della circonferenza: ");
	scanf("%d",&raggio);

	printf("Circonferenza: %d",calcola_circonfenrenza(raggio) );

	return 0;
}

double calcola_circonferenza(double raggio) {
	double risultato;

	risultato = 2*pigreco*raggio;

	return risultato;
}

Abbiamo introdotto una funzione chiamata calcola_circonfenrenza che astrae il concetto del calcolo che si propone di fare.
Se decidessimo di fornire ad un altra persona la nostra funzione, questo la potrebbe usare senza avere alcuna nozione di geometria, purché insieme alla funzione gli forniamo una spiegazione sul compito svolto e sulla forma della funzione. Un esempio di ciò è la terza riga di codice:

double calcola_circonferenza(double raggio);

chiamata intestazione della funzione, il cui unico scopo è quello di ricordare (sia al compilatore che al programmatore) quali sono le condizioni per l'uso della funzione. Nel nostro caso si ricorda che la funzione richiede in ingresso un argomento di tipo double e ne restituisce uno di tipo double.

Le intestazioni delle funzioni devono essere sempre dichiarate anche se lo standard non obbliga a farlo, perché aiutano notevolmente l'utente nella stesura del programma.
Il posto corretto in cui posizionare le intestazioni è dopo la sezione delle direttive al precompilatore

Un altro vantaggio non indifferente delle funzioni è che possono essere usate in più punti del codice. Questo permette di evitare una duplicazione di quelle parti del codice che vengono usate più volte. Se ad esempio oltre al raggio della circonferenza ci servisse anche l'altezza del cilindro per calcolare l'area, abbiamo bisogni di interrogare due volte l'utente per la richiesta dei dati.
Niente di grave, una volta che la funzione scanf effettua la richiesta, basta invocarla più volte eventualmente cambiando solo i parametri.


Bibliografia


Testi consigliati per l'apprendimento

Questo articolo è stato scaricato dal Club di informatica
Pagina curata da Luca Sabatucci